In [1]:
import matplotlib.pyplot as plt
import numpy as np
# For presentation purposes only.
%matplotlib inline
In [2]:
x = [1, 2, 3, 5] # List of x coordinates.
y = [4, 3, 6, 2] # List of y coordinates.
y_error = [0.1, 0.5, .2, 0.25] # Errors associated with the y readings.
plt.scatter(x, y)
plt.show() # Displays the plot.
plt.clf() # Clears the plot.
Three functions were called during the generation of this plot:
This plot is missing a couple of important features though:
Let's fix that.
In [3]:
plt.scatter(x, y)
plt.xlabel("X Axis")
plt.ylabel("Y Axis")
plt.title("Basic Scatterplot")
plt.grid()
plt.show()
plt.clf()
Let's say we wanted a line drawn between the points. Matplotlib has got us covered with the plot function.
In [4]:
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("y")
plt.title("Plot with Interpolated Lines")
plt.grid()
plt.show()
plt.clf()
Matplotlib has gone ahead and interpolated a line between consecutive points. However it would be useful to still show the original points. This can be achieved using the marker
keyword argument.
In [5]:
plt.plot(x, y, marker="D") # D is for diamond
plt.xlabel("x")
plt.ylabel("y")
plt.title("Plot with Interpolated Lines and Points Displayed")
plt.grid()
plt.show()
plt.clf()
There are lots of different marker styles available. A list of them can be found here.
Maplotlib has also given us some nice limits for our plot, however let's imaginge we needed the plot to show the origin.
In [6]:
plt.plot(x, y, marker="D")
plt.xlim([0, 5.2]) # Displays the x-axis from 0 to 4
plt.ylim([0, 6.4]) # Displays the y-axis from 0 to 7
plt.xlabel("x")
plt.ylabel("y")
plt.title("Plot Showing Origin")
plt.grid()
plt.show()
plt.clf()
This plot looks pretty good. Too good. Let's add in error bars using the errorbar function.
In [7]:
plt.plot(x, y, marker="x") # x is for x
plt.errorbar(x, y, yerr=y_error) # Adding in error bars.
plt.xlabel("x")
plt.ylabel("y")
plt.title("Realistic Plot")
plt.grid()
plt.show()
plt.clf()
To specify x-errors use the xerr
keyword.
In [8]:
x = np.linspace(-np.pi, np.pi, 10, endpoint=True)
y = np.sin(x)
plt.plot(x, y, marker=".")
plt.xlabel("x")
plt.ylabel("sin(x)")
plt.title("Sine Function")
plt.grid()
plt.show()
plt.clf()
A whole bunch of stuff just happened. Let's take a minute to go through it:
An important thing to wrap your head around is that plotting in Python is all about points. To plot a function you evaluate the function at many points and then plot those points. The plot above isn't particularly smooth. This can be improved by sampling more points.
In [9]:
x = np.linspace(-np.pi, np.pi, 100, endpoint=True) # Switch from 10 to 100 points.
y = np.sin(x)
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("sin(x)")
plt.title("Sine Function")
plt.grid()
plt.show()
plt.clf()
That looks much smoother. Now let's plot multiple figures in a single plot.
In [10]:
x = np.linspace(-np.pi, np.pi, 100, True)
plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
plt.xlabel("x")
plt.ylabel("y")
plt.title("Sine and Cosine Function")
plt.grid()
plt.show()
plt.clf()
This is as simple as making two calls to plot. However with two different things on the plot it's a good idea to label them.
In [11]:
x = np.linspace(-np.pi, np.pi, 100, True)
plt.plot(x, np.sin(x), label="Sin(x)") # label associates a name with the plot.
plt.plot(x, np.cos(x), label="Cos(x)")
plt.xlabel("x")
plt.ylabel("y")
plt.title("Sine and Cosine Function")
plt.legend(loc='upper left') # Display the legend in the upper right.
plt.grid()
plt.show()
plt.clf()
And that's the general gist of generating plots.
Sometimes you want to have either the x-axis
, y-axis
or both as a log scale.
In [12]:
x = np.linspace(-100, 10, 100, True)
plt.plot(x, 10**x)
plt.xlabel("x")
plt.ylabel("y")
plt.title("Power Function")
plt.grid()
plt.show()
It's hard to see what's happening to see what's happening with this power function on a normal scale. Let's clean it up using a semi-log plot.
In [13]:
plt.semilogy(x, 10**x) # Semi-Log Plot
plt.xlabel("x")
plt.ylabel("y")
plt.title("Exponential Function - Semi-Log Plot")
plt.grid()
plt.show()
If you wanted the log scale on the x-axis
you would use the semilogx
function.
For log-log plots use the loglog
function.
In [14]:
x = np.linspace(1, 10000, 50, True)
plt.loglog(x, x) # Log-log Plot
plt.xlabel("x")
plt.ylabel("y")
plt.title("Log-Log Plot")
plt.grid()
plt.show()
One thing to note is that when using a logarithmic scale, linspace
isn't the best function to use because the distribution of sample points becomes skewed visually.
In [15]:
x = np.linspace(1, 10**3, 50, True)
plt.loglog(x, x, marker="x", linestyle='None')
plt.xlabel("x")
plt.ylabel("y")
plt.title("Skewed Log-Log")
plt.grid()
plt.show()
This can be improved by using the logspace
function which takes as its first three arguments a starting power, ending power and the number of points to sample.
In [16]:
x = np.logspace(1, 3, 50, endpoint=True, base=10)
plt.loglog(x, x, marker="x", linestyle='None')
plt.xlabel("x")
plt.ylabel("y")
plt.title("Clean Log-Log")
plt.grid()
plt.show()
In [17]:
x = np.linspace(0, 10, 50)
plt.xlabel("x")
plt.ylabel("y")
plt.title("A Line")
plt.grid()
plt.plot(x, x)
plt.savefig("Line.pdf") # Save the plot.
plt.clf()
Matplotlib determines what kind of file to save the plot as based on the extension you give the savefig
function. In general you should be able to save plots with the following extensions: